package sfin.service;

import static org.apache.commons.lang.StringUtils.isBlank;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.ResourceBundle;

import sfin.swt.exception.StatizoException;
import sfin.swt.util.FormatterUtil;
import br.com.statizo.financeiro.core.repository.impl.BancoRepository;
import br.com.statizo.financeiro.domain.entity.impl.Banco;

public class BancoService extends AbstractService{

	private List<Banco> bancos;
	private BancoRepository bancoRepository;

	public BancoService(ResourceBundle bundle, FormatterUtil formatterUtil, BancoRepository bancoRepository) {
		super(bundle,formatterUtil);
		this.bancoRepository = bancoRepository;
		this.bancos = bancoRepository.getList();
		sort();
	}

	public int save(int selectedIndex, String codigo, String nome) throws StatizoException{
		List<String> messages = new ArrayList<String>();
		if(isBlank(codigo)){
			messages.add(bundle.getString("bank.edit.save.message.required.code"));
		}
		if(isBlank(nome)){
			messages.add(bundle.getString("bank.edit.save.message.required.name"));
		}
		if(messages.isEmpty()){
			Banco banco = selectedIndex == -1 ? new Banco() : bancos.get(selectedIndex);
			banco.setCodigo(codigo);
			banco.setNome(nome);
			
			bancoRepository.entityManagerRefresh();
			bancoRepository.beginTransaction();
			try{

				banco = bancoRepository.merge(banco);
				if(!bancos.contains(banco))
					bancos.add(banco);
				
				sort();
				notifyListeners();
				bancoRepository.commit();
				return bancos.indexOf(banco);				
			}catch(Exception e){
				bancoRepository.rollBack();
				messages.add(e.getMessage());
				throw new StatizoException(messages);
			}
		}else{
			throw new StatizoException(messages);
		}
	}

	public int indexOf(Banco banco){
		return bancos.indexOf(banco);
	}

	public String[] getNomes(){
		String[] names =new String[bancos.size()];
		for(int i = 0; i<bancos.size(); i++){
			Banco banco = bancos.get(i);
			names[i] = "("+banco.getCodigo() + ") " +banco.getNome();
		}
		return names;
	}

	public void sort(){
		Comparator<Banco> comparator = (b1,b2) -> b1.getNome().compareTo(b2.getNome());
		bancos.sort(comparator);
	}

	public Banco getAt(int index){
		return bancos.get(index);
	}
	
	public Banco merge(Banco banco){
		return bancoRepository.merge(banco);
	}

	public void remove(int index) throws StatizoException{
		List<String> messages = new ArrayList<String>();
		try{
			Banco banco = bancos.get(index);
			
			bancoRepository.entityManagerRefresh();
			bancoRepository.beginTransaction();
			bancoRepository.remove(banco);
			bancoRepository.commit();
			
			bancos.remove(index);
			notifyListeners();
		}catch(Exception e){
			messages.add(e.getMessage());
			throw new StatizoException(messages);
		}
	}

	public int count(){
		return bancos.size();
	}

}
